/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.impl;

import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionPath;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionProtocolElement;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionprotocolsPackage;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.Lifeline;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.Termination;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.TerminationElement;

import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.util.InteractionprotocolsValidator;
import java.util.Map;
import org.eclipse.emf.common.notify.Notification;

import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;
import org.eclipse.emf.ecore.plugin.EcorePlugin;
import org.eclipse.emf.ecore.util.EObjectValidator;



/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>Termination</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.impl.TerminationImpl#getTerminationElement <em>Termination Element</em>}</li>
 *   <li>{@link ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.impl.TerminationImpl#getLifeline <em>Lifeline</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class TerminationImpl extends InteractionProtocolElementImpl implements Termination {
	/**
	 * The default value of the '{@link #getTerminationElement() <em>Termination Element</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTerminationElement()
	 * @generated
	 * @ordered
	 */
	protected static final TerminationElement TERMINATION_ELEMENT_EDEFAULT = TerminationElement.SUCCESS;

	/**
	 * The cached value of the '{@link #getTerminationElement() <em>Termination Element</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getTerminationElement()
	 * @generated
	 * @ordered
	 */
	protected TerminationElement terminationElement = TERMINATION_ELEMENT_EDEFAULT;

	/**
	 * The cached value of the '{@link #getLifeline() <em>Lifeline</em>}' reference.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getLifeline()
	 * @generated
	 * @ordered
	 */
	protected Lifeline lifeline;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected TerminationImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return InteractionprotocolsPackage.Literals.TERMINATION;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public TerminationElement getTerminationElement() {
		return terminationElement;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setTerminationElement(TerminationElement newTerminationElement) {
		TerminationElement oldTerminationElement = terminationElement;
		terminationElement = newTerminationElement == null ? TERMINATION_ELEMENT_EDEFAULT : newTerminationElement;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, InteractionprotocolsPackage.TERMINATION__TERMINATION_ELEMENT, oldTerminationElement, terminationElement));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Lifeline getLifeline() {
		if (lifeline != null && lifeline.eIsProxy()) {
			InternalEObject oldLifeline = (InternalEObject)lifeline;
			lifeline = (Lifeline)eResolveProxy(oldLifeline);
			if (lifeline != oldLifeline) {
				if (eNotificationRequired())
					eNotify(new ENotificationImpl(this, Notification.RESOLVE, InteractionprotocolsPackage.TERMINATION__LIFELINE, oldLifeline, lifeline));
			}
		}
		return lifeline;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public Lifeline basicGetLifeline() {
		return lifeline;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setLifeline(Lifeline newLifeline) {
		Lifeline oldLifeline = lifeline;
		lifeline = newLifeline;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, InteractionprotocolsPackage.TERMINATION__LIFELINE, oldLifeline, lifeline));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean terminationVerification(DiagnosticChain diagnostics, Map context) {
		// TODO: implement this method
		// -> specify the condition that violates the invariant
		// -> verify the details of the diagnostic, including severity and message
		// Ensure that you remove @generated or mark it @generated NOT
		if (validateNotAndParent()) {
			if (diagnostics != null) {
				diagnostics.add
					(new BasicDiagnostic
						(Diagnostic.ERROR,
						 InteractionprotocolsValidator.DIAGNOSTIC_SOURCE,
						 InteractionprotocolsValidator.TERMINATION__TERMINATION_VERIFICATION,
						 EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "Must not have an And ascendant", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$
						 new Object [] { this }));
			}
			return false;
		}
		return true;
	}

	
	 /**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean orVerification(DiagnosticChain diagnostics, Map context) {
		// TODO: implement this method
		// -> specify the condition that violates the invariant
		// -> verify the details of the diagnostic, including severity and message
		// Ensure that you remove @generated or mark it @generated NOT
		if (validateNotOrParent()) {
			if (diagnostics != null) {
				diagnostics.add
					(new BasicDiagnostic
						(Diagnostic.ERROR,
						 InteractionprotocolsValidator.DIAGNOSTIC_SOURCE,
						 InteractionprotocolsValidator.TERMINATION__OR_VERIFICATION,
						 EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "orVerification", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$
						 new Object [] { this }));
			}
			return false;
		}
		return true;
	}

		/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean cancelVerification(DiagnosticChain diagnostics, Map context) {
		// TODO: implement this method
		// -> specify the condition that violates the invariant
		// -> verify the details of the diagnostic, including severity and message
		// Ensure that you remove @generated or mark it @generated NOT
		if (validateNotCancelParent()) {
			if (diagnostics != null) {
				diagnostics.add
					(new BasicDiagnostic
						(Diagnostic.ERROR,
						 InteractionprotocolsValidator.DIAGNOSTIC_SOURCE,
						 InteractionprotocolsValidator.TERMINATION__CANCEL_VERIFICATION,
						 EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "cancelVerification", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$
						 new Object [] { this }));
			}
			return false;
		}
		return true;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean exceptionTerminationVerification(DiagnosticChain diagnostics, Map context) {
		// TODO: implement this method
		// -> specify the condition that violates the invariant
		// -> verify the details of the diagnostic, including severity and message
		// Ensure that you remove @generated or mark it @generated NOT
		if (validateNotExceptionParent()) {
			if (diagnostics != null) {
				diagnostics.add
					(new BasicDiagnostic
						(Diagnostic.ERROR,
						 InteractionprotocolsValidator.DIAGNOSTIC_SOURCE,
						 InteractionprotocolsValidator.TERMINATION__EXCEPTION_TERMINATION_VERIFICATION,
						 EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "exceptionTerminationVerification", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$
						 new Object [] { this }));
			}
			return false;
		}
		return true;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean terminationFirstLevelVerification(DiagnosticChain diagnostics, Map context) {
		// TODO: implement this method
		// -> specify the condition that violates the invariant
		// -> verify the details of the diagnostic, including severity and message
		// Ensure that you remove @generated or mark it @generated NOT
//		if ((this.eContainer().getClass()==(InteractionProtocolImpl.class))) {
		if (this.getSuccessor()!=null) { // Esta incompleto, falta que busque en los sucesores no directos.-
			if (diagnostics != null) {
				diagnostics.add
					(new BasicDiagnostic
						(Diagnostic.ERROR,
						 InteractionprotocolsValidator.DIAGNOSTIC_SOURCE,
						 InteractionprotocolsValidator.TERMINATION__TERMINATION_FIRST_LEVEL_VERIFICATION,
						 EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "A Termination cannot be folowed by any element", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$
						 new Object [] { this }));
			}
			return false;
		}
		return true;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean whileTerminationVerification(DiagnosticChain dignostics, Map context) {
		// TODO: implement this method
		// -> specify the condition that violates the invariant
		// -> verify the details of the diagnostic, including severity and message
		// Ensure that you remove @generated or mark it @generated NOT
		if (validateNotLoopParent()) {
			if (dignostics != null) {
				dignostics.add
					(new BasicDiagnostic
						(Diagnostic.ERROR,
						 InteractionprotocolsValidator.DIAGNOSTIC_SOURCE,
						 InteractionprotocolsValidator.TERMINATION__WHILE_TERMINATION_VERIFICATION,
						 EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "whileTerminationVerification", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$
						 new Object [] { this }));
			}
			return false;
		}
		return true;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean untilTerminationVerification(DiagnosticChain diagnostics, Map context) {
		// TODO: implement this method
		// -> specify the condition that violates the invariant
		// -> verify the details of the diagnostic, including severity and message
		// Ensure that you remove @generated or mark it @generated NOT
		if (false) {
			if (diagnostics != null) {
				diagnostics.add
					(new BasicDiagnostic
						(Diagnostic.ERROR,
						 InteractionprotocolsValidator.DIAGNOSTIC_SOURCE,
						 InteractionprotocolsValidator.TERMINATION__UNTIL_TERMINATION_VERIFICATION,
						 EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "untilTerminationVerification", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$
						 new Object [] { this }));
			}
			return false;
		}
		return true;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public boolean multipleInstanceTerminationVerification(DiagnosticChain diagnostics, Map context) {
		// TODO: implement this method
		// -> specify the condition that violates the invariant
		// -> verify the details of the diagnostic, including severity and message
		// Ensure that you remove @generated or mark it @generated NOT
		if (validateNotMIParent()) {
			if (diagnostics != null) {
				diagnostics.add
					(new BasicDiagnostic
						(Diagnostic.ERROR,
						 InteractionprotocolsValidator.DIAGNOSTIC_SOURCE,
						 InteractionprotocolsValidator.TERMINATION__MULTIPLE_INSTANCE_TERMINATION_VERIFICATION,
						 EcorePlugin.INSTANCE.getString("_UI_GenericInvariant_diagnostic", new Object[] { "multipleInstanceTerminationVerification", EObjectValidator.getObjectLabel(this, context) }), //$NON-NLS-1$ //$NON-NLS-2$
						 new Object [] { this }));
			}
			return false;
		}
		return true;
	}

	private boolean validateNotExceptionParent() {
		 
		 InteractionProtocolElement ie = this;
		 InteractionPath ip = null;
		 
		 if(ie.eContainer() == null) return false;
		 
		 while(!(ie.eContainer().getClass()==(InteractionProtocolImpl.class))) {
			 if((ie.eContainer().getClass()==(InteractionPathImpl.class))) 
			 {
				 ip = (InteractionPath) ie.eContainer();
			 }
			 else if((ie.eContainer().getClass()==(InteractionProtocolImpl.class))) return false;
			 ie = (InteractionProtocolElement) ip.eContainer();
			 if(ie.getClass() == null) return true;
			 if(ie.getClass()==(ExceptionImpl.class)) return true;
				
			 
		 }
		 return false;
		 
	}	

	private boolean validateNotMIParent() {
		 
		 InteractionProtocolElement ie = this;
		 InteractionPath ip = null;
		 
		 if(ie.eContainer() == null) return false;
		 
		 while(!(ie.eContainer().getClass()==(InteractionProtocolImpl.class))) {
			 if((ie.eContainer().getClass()==(InteractionPathImpl.class))) 
			 {
				 ip = (InteractionPath) ie.eContainer();
			 }
			 else if((ie.eContainer().getClass()==(InteractionProtocolImpl.class))) return false;
			 ie = (InteractionProtocolElement) ip.eContainer();
			 if(ie.getClass() == null) return true;
			 if(ie.getClass()==(MultipleInstanceImpl.class)) return true;
				
			 
		 }
		 return false;
		 
	}	

	
	private boolean validateNotLoopParent() { 
		 
		 InteractionProtocolElement ie = this;
		 InteractionPath ip = null;
		 
		 if(ie.eContainer() == null) return false;
		 
		 while(!(ie.eContainer().getClass()==(InteractionProtocolImpl.class))) {
			 if((ie.eContainer().getClass()==(InteractionPathImpl.class))) 
			 {
				 ip = (InteractionPath) ie.eContainer();
			 }
			 else if((ie.eContainer().getClass()==(InteractionProtocolImpl.class))) return false;
			 ie = (InteractionProtocolElement) ip.eContainer();
			 if(ie.getClass() == null) return true;
			 if(ie.getClass()==(LoopImpl.class)) return true;
				
			 
		 }
		 return false;
		 
	}	
	
	private boolean validateNotUntilParent() { 
		 
		 InteractionProtocolElement ie = this;
		 InteractionPath ip = null;
		 
		 if(ie.eContainer() == null) return false;
		 
		 while(!(ie.eContainer().getClass()==(InteractionProtocolImpl.class))) {
			 if((ie.eContainer().getClass()==(InteractionPathImpl.class))) 
			 {
				 ip = (InteractionPath) ie.eContainer();
			 }
			 else if((ie.eContainer().getClass()==(InteractionProtocolImpl.class))) return false;
			 ie = (InteractionProtocolElement) ip.eContainer();
			 if(ie.getClass() == null) return true;
			 if(ie.getClass()==(AndImpl.class)) return true;
				
			 
		 }
		 return false;
		 
	}	
	

	private boolean validateNotAndParent() {
		 
		 InteractionProtocolElement ie = this;
		 InteractionPath ip = null;
		 
		 if(ie.eContainer() == null) return false;
		 
		 while(!(ie.eContainer().getClass()==(InteractionProtocolImpl.class))) {
			 if((ie.eContainer().getClass()==(InteractionPathImpl.class))) 
			 {
				 ip = (InteractionPath) ie.eContainer();
			 }
			 else if((ie.eContainer().getClass()==(InteractionProtocolImpl.class))) return false;
			 ie = (InteractionProtocolElement) ip.eContainer();
			 if(ie.getClass() == null) return true; 
			 if(ie.getClass()==(AndImpl.class)) return true;
				
			 
		 }
		 return false;
		 
	}
		
	private boolean validateNotCancelParent() {
		 
		 InteractionProtocolElement ie = this;
		 InteractionPath ip = null;
		 
		 if(ie.eContainer() == null) return false;
		 
		 while(!(ie.eContainer().getClass()==(InteractionProtocolImpl.class))) {
			 if((ie.eContainer().getClass()==(InteractionPathImpl.class))) 
			 {
				 ip = (InteractionPath) ie.eContainer();
			 }
			 else if((ie.eContainer().getClass()==(InteractionProtocolImpl.class))) return false;
			 ie = (InteractionProtocolElement) ip.eContainer();
			 if(ie.getClass() == null) return true;
			 if(ie.getClass()==(CancelImpl.class)) return true;
				
			 
		 }
		 return false;
		 
	}

		private boolean validateNotOrParent() {
			 
			 InteractionProtocolElement ie = this;
			 InteractionPath ip = null;
			 
			 if(ie.eContainer() == null) return false;
			 
			 while(!(ie.eContainer().getClass()==(InteractionProtocolImpl.class))) {
				 if((ie.eContainer().getClass()==(InteractionPathImpl.class))) 
				 {
					 ip = (InteractionPath) ie.eContainer();
				 }
				 else if((ie.eContainer().getClass()==(InteractionProtocolImpl.class))) return false;
				 ie = (InteractionProtocolElement) ip.eContainer();
				 if(ie.getClass() == null) return true;
				 if(ie.getClass()==(OrImpl.class)) return true;
					
			 }
			 return false;
			 
		}
		
	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case InteractionprotocolsPackage.TERMINATION__TERMINATION_ELEMENT:
				return getTerminationElement();
			case InteractionprotocolsPackage.TERMINATION__LIFELINE:
				if (resolve) return getLifeline();
				return basicGetLifeline();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case InteractionprotocolsPackage.TERMINATION__TERMINATION_ELEMENT:
				setTerminationElement((TerminationElement)newValue);
				return;
			case InteractionprotocolsPackage.TERMINATION__LIFELINE:
				setLifeline((Lifeline)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case InteractionprotocolsPackage.TERMINATION__TERMINATION_ELEMENT:
				setTerminationElement(TERMINATION_ELEMENT_EDEFAULT);
				return;
			case InteractionprotocolsPackage.TERMINATION__LIFELINE:
				setLifeline((Lifeline)null);
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case InteractionprotocolsPackage.TERMINATION__TERMINATION_ELEMENT:
				return terminationElement != TERMINATION_ELEMENT_EDEFAULT;
			case InteractionprotocolsPackage.TERMINATION__LIFELINE:
				return lifeline != null;
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (terminationElement: "); //$NON-NLS-1$
		result.append(terminationElement);
		result.append(')');
		return result.toString();
	}

} //TerminationImpl
